home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
PASCAL
/
MISC_ROU
/
HFSSCN.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1989-12-02
|
9KB
|
272 lines
PROGRAM HFSScan7 (Input, Output);
{This program has been built from bits and pieces shamelessly lifted from
various Apple Tech Notes, mostly no.s 24, 66, and 68. I have put in a few
items of my own, mostly the glue between the tech notes.
The intent of this pearl is to feel around HFS amd to devise a scheme for
locating a "beacon" file in ANY volume under any file system. Any file name
can be used (e.g., Desktop, Neil Konzen). At present the HFS scanner only
does the default volume but the MFS scanner does 'em all. Each MFS pass will
finally end with -43 when all files are exhausted. Don't worry about it.
This is a "work in progress" but it is offered in response to those folks who
have been asking about HFS and how to find a file. What is missing most
prominently (aside from good coding technique and design!) is the traverse
down the DirID tree once the "beacon" is found - with this and the volume name
one has... a complete pathname! As the old text book copout goes: we leave
this as an exercise for the student...
Oh, about the "$I HardDisk-20:TMLPascal:relFldr:etc."; those are my names
on my HardDisk-20 for my TML files. Change them to match your system.
Cheers and encouragement, praise, good words may be sent to me - boos, jeers,
and derision may be sent to the nearest bit-bucket. Enjoy!
Signed,
Rick Emerson (76254,421)
for The System Support Group,
"The folks to call when you don't
understand it all."
Notice: This work is offered "as is" and no warranty of any sort is expressly
stated or implied.
}
{$I HardDisk-20:TMLPascal:relFldr:MemTypes.ipas }
{$I HardDisk-20:TMLPascal:relFldr:QuickDraw.ipas }
{$I HardDisk-20:TMLPascal:relFldr:OSIntf.ipas }
{$I HardDisk-20:TMLPascal:relFldr:HFS.ipas }
{$I HardDisk-20:TMLPascal:relFldr:ToolIntf.ipas }
{$I HardDisk-20:TMLPascal:relFldr:PackIntf.ipas }
VAR
targetString: Str255;
targetStrPtr: StringPtr;
myOSErr: OSErr;
whichVol: INTEGER;
whichFile: INTEGER;
myVolRef: INTEGER;
myVolName: Str255;
myPathname: Str255;
isamErr: INTEGER;
volumeOK: BOOLEAN;
fileOK: BOOLEAN;
filePB: ParamBlockRec;
homeNamePtr: StringPtr;
homeVolRefNo: INTEGER;
homeRefNum: INTEGER;
dummy: CHAR;
dummyStr: Str255;
dummyPtr: StringPtr;
FUNCTION GetIndVolume (whichVol:INTEGER;
VAR volName: Str255;
VAR volRef: INTEGER): OSErr;
{*
* GetIndVolume: return the name and volume reference number of a volume,
* specified by whichVol. From Macintosh Technote #24 by Bryan Stearns.
*}
VAR
volPB: ParamBlockRec;
anErr: OSErr;
BEGIN
WITH volPB DO BEGIN {makes it easier to fill fields in!}
ioCompletion := NIL;
ioNamePtr := @volName; {make sure it returns the name}
ioVRefNum := 0; {to determine which volume}
ioVolIndex := whichVol; {use this to determine the volume}
anErr := PBGetVInfo(@volPB,FALSE); {do it (FALSE = synchronously)}
GetIndVolume := anErr; {return error code}
IF anErr = noErr THEN BEGIN {if no error occurred }
volRef := ioVRefNum; { return the vol info}
END; {if no error}
END; {with}
END {GetIndVolume};
PROCEDURE EnumerShell(DirIDToSearch: LongInt);
{From Macintosh Technote #68 by Jim Friedlander.}
VAR
myCPB: CInfoPBRec;
err: OSErr;
myWDPB: WDPBRec;
TotalFiles,TotalDirectories: INTEGER;
fName: Str255;
PROCEDURE EnumerateCatalog(dirIDToSearch: LongInt);
VAR
index: INTEGER;
BEGIN {EnumerateCatalog}
index:= 1;
REPEAT
FName:= ''; {nil out name}
myCPB.ioCompletion := NIL;
myCPB.ioVRefNum := myWDPB.ioVRefNum; {Look in current working vol}
myCPB.ioFDirIndex:= index;
myCPB.ioDrDirID:= dirIDToSearch; {we need to do this every time through}
err:= PBGetCatInfo(@myCPB,FALSE);
IF err = noErr THEN
IF BitTst(@myCPB.ioFlAttrib,3) THEN
BEGIN {directory bit set}
TotalDirectories:=TotalDirectories+1;
EnumerateCatalog(myCPB.ioDrDirID);
err:= 0; {clear error return on way back}
END
ELSE
BEGIN{directory bit cleared - we have a file}
TotalFiles:= TotalFiles + 1;
IF EqualString (myCPB.ioNamePtr^, targetString, FALSE, FALSE) THEN
BEGIN
Write (myCPB.ioNamePtr^, ' and ', targetString, ' match! ');
WriteLn (' myCPB.ioVRefNum = ', myCPB.ioVRefNum);
WriteLn (' myCPB.ioFlNum = ', myCPB.ioFlNum);
END {IF};
END {IF};
index:= index + 1;
UNTIL err <> noErr;
END {EnumerateCatalog};
BEGIN {EnumerShell}
TotalFiles:= 0;
TotalDirectories:= 0;
fName:= ''; {nil out name}
myWDPB.ioCompletion := NIL; {Set up a default vol & dir...}
myWDPB.ioNamePtr := NIL; {...so we have a definite starting...}
myWDPB.ioVRefNum := 0; {...point to search from.}
myWDPB.ioWDDirID := 0;
err := PBHSetVol (@myWDPB, FALSE); {Make us a default}
dummyStr := '';
dummyPtr := @dummyStr;
myWDPB.ioCompletion := NIL;
myWDPB.ioNamePtr := dummyPtr; {Demand a name by using a null string}
err:= PBHGetVol(@myWDPB,FALSE); {get the default volume}
WriteLn ('Starting with vol ->', myWDPB.ioNamePtr^, '<- & WDVRefNum =',
myWDPB.ioWDVRefNum);
WriteLn ('ioVRefNum = ', myWDPB.ioVRefNum);
WITH MyCPB DO BEGIN
iocompletion:= NIL;
ioNamePtr:= @FName;
ioVRefNum:= myWDPB.ioVRefNum; {For now this is the default vol...}
{...change it to scout other vols}
END {WITH};
EnumerateCatalog(2);{DirID 2, the root level}
Write (totalDirectories, ' directories searched and ');
WriteLn (totalFiles, ' files searched.');
END {EnumerShell};
FUNCTION IsItHFS : BOOLEAN;
{From Macintosh Technote #66 by Jim Friedlander.}
CONST
FSFCBLen= $3F6; {address of the low-memory global}
VAR
HFS: ^INTEGER;
BEGIN
HFS:= POINTER(FSFCBLen);
IF HFS^ > 0 THEN
IsItHFS := TRUE {we're running HFS}
ELSE
IsItHFS := FALSE; {we're running MFS}
END {IsItHFS};
BEGIN
targetString := 'HomeBeacon'; {Can we find this file somewhere?}
targetStrPtr := @targetString;
whichVol := 1;
volumeOK := TRUE;
WHILE volumeOK DO
BEGIN
myOSErr := GetIndVolume (whichVol, myVolName, myVolRef);
IF (myOSErr = nsvErr) THEN
volumeOK := FALSE
ELSE
BEGIN
Write ('ioVolIndex = ', whichVol, ' volName ->', myVolName, '<- ');
WriteLn (' volRef = ', myVolRef);
whichVol := whichVol + 1;
END {IF};
END {WHILE};
IF IsItHFS THEN BEGIN
WriteLn ('This is coming to you via HFS!');
EnumerShell(0); {Go look for truth, beauty and... HomerBeacon?}
END
ELSE
BEGIN
WriteLn ('This has all the earmarks of MFS.');
dummyStr := '';
dummyPtr := @dummyStr;
whichVol := 1;
volumeOK := TRUE;
WHILE volumeOK DO {Page through the vols looking for HomerBeacon}
BEGIN
myOSErr := GetIndVolume (whichVol, myVolName, myVolRef);
IF (myOSErr = nsvErr) THEN
volumeOK := FALSE
ELSE
BEGIN
whichFile := 1; {Page through the files looking for HomerBeacon}
fileOK := TRUE;
WHILE fileOK DO
BEGIN
WITH filePB DO
BEGIN
ioCompletion := NIL;
ioVRefNum := myVolRef;
ioNamePtr := dummyPtr; {Clear name pointer}
ioFDirIndex := whichFile;
ioFVersNum := 0;
myOSErr := PBGetFInfo(@filePB,FALSE); {FALSE = synchronously}
IF (myOSErr = noErr) THEN
BEGIN
IF (targetStrPtr^=ioNamePtr^) THEN
BEGIN
homeNamePtr := ioNamePtr; {Mark it for...}
homeVolRefNo := ioVRefNum; {...later recall}
WriteLn (targetStrPtr^, ' and ', ioNamePtr^,
' matched up!');
ioCompletion := NIL; {Do an open to...}
ioNamePtr := homeNamePtr; {...prove we really found...}
ioVRefNum := homeVolRefNo; {...the file in MFS land}
ioFVersNum := 0; {Per Mike Cohen & IM}
ioPermssn := 0; {Allow whatever is OK now}
ioMisc := NIL; {Use vol buffer}
myOSErr := PBOpen(@filePB,FALSE);
IF (myOSErr = noErr) THEN
BEGIN
WriteLn ('File opened OK');
homeRefNum := ioRefNum;
ioCompletion := NIL; {Nice, now put it back!}
ioRefNum := homeRefNum;
myOSErr := PBClose (@filePB, FALSE);
WriteLn ('After close OSErr = ', myOSErr);
END
ELSE
BEGIN {Close, but no luck - You lose}
WriteLn ('Unable to open ', ioNamePtr^);
WriteLn ('OSErr = ', myOSErr);
END {IF};
END
ELSE
WriteLn (' ');
whichFile := whichFile + 1;
END {IF};
END {WHILE};
END {WITH};
whichVol := whichVol + 1;
END {IF};
END {WHILE};
END {IF};
WriteLn ('Search done - Hit RETURN to quit');
ReadLn (dummy); {Wait for this to be read}
END {HFSScan}.